package net.simflow.swf.analyzer.network.stats.opt;

import java.util.ArrayList;
import java.util.TreeMap;

import net.simflow.swf.analyzer.network.data.Network;
import net.simflow.swf.analyzer.network.data.Node;

public class NetworkDegreeDistributionAnalyzer {

	private final static int DEGREE_STYLE_ALL = 0;
	private final static int DEGREE_STYLE_IN = 1;
	private final static int DEGREE_STYLE_OUT = 2;
	private final static int DEGREE_STYLE_IN_DATA = 3;
	private final static int DEGREE_STYLE_IN_CONTROL = 4;
	private final static int DEGREE_STYLE_OUT_DATA = 5;
	private final static int DEGREE_STYLE_OUT_CONTROL = 6;

	private static NetworkDegreeDistributionAnalyzer instance = new NetworkDegreeDistributionAnalyzer();

	private NetworkDegreeDistributionAnalyzer() {
	}

	public static NetworkDegreeDistributionAnalyzer getInstance() {
		return instance;
	}

	public TreeMap<Integer, ArrayList<Node>> analyze(Network network) {
		return analyze(network, DEGREE_STYLE_ALL);
	}

	private TreeMap<Integer, ArrayList<Node>> analyze(Network network, int style) {
		if (network == null) {
			return null;
		}

		TreeMap<Integer, ArrayList<Node>> map = new TreeMap<Integer, ArrayList<Node>>();

		for (Node n : network.getNodeSet()) {
			int degree;

			switch (style) {
			case DEGREE_STYLE_ALL:
				degree = n.getLinkCount();
				break;
			case DEGREE_STYLE_IN:
				degree = n.getParentCount();
				break;
			case DEGREE_STYLE_OUT:
				degree = n.getChildCount();
				break;
			case DEGREE_STYLE_IN_DATA:
				degree = n.getParentDataSet().size();
				break;
			case DEGREE_STYLE_IN_CONTROL:
				degree = n.getParentControlSet().size();
				break;
			case DEGREE_STYLE_OUT_DATA:
				degree = n.getChildDataSet().size();
				break;
			case DEGREE_STYLE_OUT_CONTROL:
				degree = n.getChildControlSet().size();
				break;
			default:
				degree = -1;
			}

			ArrayList<Node> array = map.get(degree);
			if (array == null) {
				array = new ArrayList<Node>();
				map.put(degree, array);
			}
			array.add(n);

		}

		map.comparator();

		return map;
	}
}
